#!/usr/bin/env python3.2
"""WikiBase parent class for pydblite databases

Sub-class WikiBase and define a new __init__ method to open a 
specific flavour of pydblite (native Base or SQLite)
"""
import os
from datetime import datetime

def _log(self, *args):
    import sys
    for arg in args:
        sys.stderr.write('%s\n' % arg)

class Page(dict):
    def __init__(self,record=None,**kw):
        defaults = {
            'name':None,
            'content':'',
            'admin':None,
            'nbvisits':0,
            'created':datetime.now(),
            'version':0,
            'lastmodif':datetime.now()
            }
        for key in kw:
            if key not in defaults:
                raise AttributeError('Invalid attribute: %s' % key)
        if record is None:
            object.__setattr__(self, 'record', {})
            defaults.update(kw)
            object.__setattr__(self, 'updates', defaults)
        else:
            object.__setattr__(self, 'record', record)
            object.__setattr__(self, 'updates', {})
        object.__setattr__(self, 'defaults', defaults)
            
    def __getattr__(self,attr):
        try:
            return self.updates[attr]
            #~ return object.__getattribute__(self,'updates')[attr]
        except KeyError:
            return self.record[attr]
    def __setattr__(self,attr,value):
        if attr not in object.__getattribute__(self,'defaults'):
            raise AttributeError('Invalid attribute: %s' % attr)
        else:
            self.updates[attr] = value
    def __bool__(self):
        return bool(self.record)
    def as_dict(self):
        #~ res = object.__getattribute__(self,'record').copy()
        #~ res.update(object.__getattribute__(self,'updates'))
        res = self.record.copy()
        res.update(self.updates)
        return res
    def __str__(self):
        return 'record: %s, updates: %s' % (str(self.record),str(self.updates))

class WikiBase(object):
    def __init__(self,path,backend='sqlite'):
        if backend == 'sqlite':        
            self._init_sqlite(path)
        else:
            self._init_base(path)
    def _init_base(self, path):
        from PyDbLite import PyDbLite
        self.db = PyDbLite.Base(path)
        self.db.create('name','content','admin','nbvisits','created',
            'version','lastmodif',mode="open")
        self.db.create_index('name')
    def _init_sqlite(self, path):
        from PyDbLite.SQLite import Database, Table
        conn = Database(path)
        table = Table('wiki', conn)
        table.create(
            ('name','TEXT'),
            ('content','TEXT'),
            ('admin','INTEGER'),
            ('nbvisits','INTEGER'),
            ('created','BLOB'),
            ('version','INTEGER'),
            ('lastmodif','BLOB'),
            mode="open")
        table.is_datetime('created')
        table.is_datetime('lastmodif')
        self.db = table
    def get(self,name):
        """Get a page record
        Return an empty record if the page does not exist
        """
        records = self.db(name=name)
        if records:
            return Page(records[0])
        else:
            return Page(None,name=name)
    def put(self,page):
        if page:
            self.db.update(page.record,**page.updates)
        else:
            self.db.insert(**page.updates)
        self.db.commit()
    def delete(self,name):
        self.db.delete(self.db(name=name))
        self.db.commit()
    def iter_pages(self,orderby='name',desc=False,limit=0):
        _log('iter_pages')
        items = [(r[orderby],r['__id__']) for r in self.db]
        items.sort()
        if desc:
            items.reverse()
        if limit > 0:
            items = items[:limit]
        for val,_id in items:
            page = Page(self.db[_id])
            _log(page)
            yield page
    def pagelist(self,orderby='name',desc=False,limit=0):
        return [p for p in self.iter_pages(orderby=orderby,desc=desc,limit=limit)]

if __name__ == "__main__":
    page = Page()
    print(bool(page))
    page.name = 'TestPage'
    page.content = 'Text'
    print('page.name:', page.name)
    print('page:', page)
    print(page.as_dict())
